package com.google.code.chaotic.model;

import java.io.Serializable;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import javax.jdo.annotations.Element;
import javax.jdo.annotations.Extension;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

//

@PersistenceCapable
public class CommutingService implements Serializable {

	/** @uml.property name="id" */
	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	@Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
	private String id;

	@Persistent
	@Extension(vendorName = "datanucleus", key = "gae.pk-id", value = "true")
	private Long decodedId;

	/** @uml.property name="origin" */
	@Persistent
	@javax.jdo.annotations.Embedded(members = {
			@Persistent(name = "latitude", columns = @javax.jdo.annotations.Column(name = "origLat")),
			@Persistent(name = "longitude", columns = @javax.jdo.annotations.Column(name = "origLon")) })
	private LatLon origin;

	/** @uml.property name="destination" */
	@Persistent
	@javax.jdo.annotations.Embedded(members = {
			@Persistent(name = "latitude", columns = @javax.jdo.annotations.Column(name = "destLat")),
			@Persistent(name = "longitude", columns = @javax.jdo.annotations.Column(name = "destLon")) })
	private LatLon destination;

	/** @uml.property name="departureTime" */
	@Persistent
	private Date departureTime;

	/** @uml.property name="arrivalTime" */
	@Persistent
	private Date arrivalTime;

	// // I keep the following as a sample many-to-many config
	// /**
	// * @uml.property name="habitsToServe"
	// * @uml.associationEnd multiplicity="(0 -1)" ordering="true"
	// * aggregation="composite" inverse=
	// * "commutingService:com.google.code.chaotic.model.CommutingHabit"
	// */
	// @ManyToMany(cascade = CascadeType.ALL)
	// @JoinTable(name = "habit_in_service", joinColumns = @JoinColumn(name =
	// "f_service_id", referencedColumnName = "id"), inverseJoinColumns =
	// @JoinColumn(name = "f_habit_id", referencedColumnName = "id"))
	// private List<CommutingHabit> habitsToServe = new
	// LinkedList<CommutingHabit>();

	/**
	 * @uml.property name="habits"
	 * @uml.associationEnd multiplicity="(0 -1)" ordering="true"
	 *                     aggregation="composite" inverse=
	 *                     "service:com.google.code.chaotic.model.HabitInService"
	 */
	@Persistent(mappedBy = "service", defaultFetchGroup = "true")
	@Element(dependent = "true")
	private List<HabitInService> habits = new LinkedList<HabitInService>();

	/**
	 * @uml.property name="waypoints"
	 * @uml.associationEnd multiplicity="(0 -1)" ordering="true"
	 *                     aggregation="composite" inverse=
	 *                     "commutingService:com.google.code.chaotic.model.ServiceWaypoint"
	 */
	@Persistent(mappedBy = "commutingService", defaultFetchGroup = "true")
	@Element(dependent = "true")
	private List<ServiceWaypoint> waypoints = new LinkedList<ServiceWaypoint>();

	/** @uml.property name="finalized" */
	@Persistent
	private boolean finalized;

	//

	/** @uml.property name="id" */
	public void setId(String id) {
		this.id = id;
	}

	/** @uml.property name="id" */
	public String getId() {
		return id;
	}

	public Long getDecodedId() {
		return decodedId;
	}

	/** @uml.property name="origin" */
	public LatLon getOrigin() {
		return origin;
	}

	/** @uml.property name="origin" */
	public void setOrigin(LatLon origin) {
		this.origin = origin;
	}

	/** @uml.property name="destination" */
	public LatLon getDestination() {
		return destination;
	}

	/** @uml.property name="destination" */
	public void setDestination(LatLon destination) {
		this.destination = destination;
	}

	/** @uml.property name="departureTime" */
	public Date getDepartureTime() {
		return departureTime;
	}

	/** @uml.property name="departureTime" */
	public void setDepartureTime(Date departureTime) {
		this.departureTime = departureTime;
	}

	/** @uml.property name="arrivalTime" */
	public Date getArrivalTime() {
		return arrivalTime;
	}

	/** @uml.property name="arrivalTime" */
	public void setArrivalTime(Date arrivalTime) {
		this.arrivalTime = arrivalTime;
	}

	/** @uml.property name="habits" */
	public List<HabitInService> getHabits() {
		return habits;
	}

	/** @uml.property name="habits" */
	public void setHabits(List<HabitInService> habits) {
		this.habits = habits;
	}

	/** @uml.property name="waypoints" */
	public List<ServiceWaypoint> getWaypoints() {
		return waypoints;
	}

	/** @uml.property name="waypoints" */
	public void setWaypoints(List<ServiceWaypoint> waypoints) {
		this.waypoints = waypoints;
	}

	/** @uml.property name="finalized" */
	public void setFinalized(boolean finalized) {
		this.finalized = finalized;
	}

	/** @uml.property name="finalized" */
	public boolean isFinalized() {
		return finalized;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + ((origin == null) ? 0 : origin.hashCode());
		return result;
	}

	// @Override
	// public int hashCode() {
	// return id != null ? id.hashCode() : 0;
	// }
}
